package com.cloud.school.app.service.impl;

import com.cloud.school.app.entity.TbComment;
import com.cloud.school.app.mapstruct.ICommentConvertMapper;
import com.cloud.school.app.model.CommentModel;
import com.cloud.school.app.model.ImageModel;
import com.cloud.school.app.model.ShowModel;
import com.cloud.school.app.model.UserModel;
import com.cloud.school.app.repository.TbCommentMapper;
import com.cloud.school.app.service.CommentService;
import com.cloud.school.app.service.ImageService;
import com.cloud.school.app.service.ShowService;
import com.cloud.school.app.service.UserService;
import com.cloud.school.app.util.IdWorker;
import com.cloud.school.app.util.exception.SystemHandleException;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName CommentServiceImpl
 * @Description TODO
 * @Author 36297
 * @Date 2018/12/14 0:53
 * @Version 1.0
 */
@Service
public class CommentServiceImpl implements CommentService {
    public static final String USER_NEW_COMMENT = "newComment.userId";

    @Autowired
    private TbCommentMapper tbCommentMapper;
    @Autowired
    private ICommentConvertMapper commentConvertMapper;
    @Autowired
    private IdWorker commentIdWorker;
    @Autowired
    private ImageService imageService;
    @Autowired
    private UserService userService;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private ShowService showService;

    @Override
    public List<CommentModel> queryByShowId(Long showId) {
        TbComment tbComment = new TbComment();
        tbComment.setShowId(showId);
        List<CommentModel> result = commentConvertMapper.entityToModel(tbCommentMapper.select(tbComment));
        appendImage(result);
        appendUser(result);
        return result;
    }

    @Override
    public List<CommentModel> queryByShowIds(List<Long> showIds) {
        showIds = showIds.stream().distinct().collect(Collectors.toList());
        Example example = new Example(TbComment.class);
        example.createCriteria().andIn("showId", showIds);
        return commentConvertMapper.entityToModel(tbCommentMapper.selectByExample(example));
    }

    @Override
    public List<CommentModel> queryDetailByShowIds(List<Long> showIds) {
        List<CommentModel> result = queryByShowIds(showIds);
        appendUser(result);
        appendImage(result);
        return result;
    }

    private void appendUser(List<CommentModel> result) {
        List<Long> uids = result.stream().map(c -> c.getCreateUid()).filter(id -> id != null).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(uids)) {
            Map<Long, UserModel> userModelMap = userService.queryDetailByIds(uids).stream().collect(Collectors.toMap(UserModel::getId, u -> u));
            result.forEach(c -> c.setCreator(userModelMap.get(c.getCreateUid())));
        }
    }

    private void appendImage(List<CommentModel> result) {
        List<Long> imageIds = result.stream().map(s -> s.getImages()).flatMap(images -> images.stream()).filter(id -> id != null).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(imageIds)) {
            Map<Long, ImageModel> imageModelMap = imageService.seleteByIds(imageIds).stream().collect(Collectors.toMap(ImageModel::getId, i -> i));
            result.forEach(commentModel -> commentModel.setImageModels(getByIdsString(imageModelMap, commentModel.getImages())));
        }
    }

    private List<ImageModel> getByIdsString(Map<Long, ImageModel> imageModelMap, List<Long> ids) {
        List<ImageModel> list = Lists.newArrayList();
        ids.forEach(id -> list.add(imageModelMap.get(id)));
        return list;
    }

    @Override
    @Transactional
    public boolean save(CommentModel commentModel) {
        if (commentModel.getPrevId() != null && tbCommentMapper.selectByPrimaryKey(commentModel.getPrevId()) == null) {
            throw new SystemHandleException("上一评论不存在!");
        }
        TbComment comment = commentConvertMapper.modelToEntity(commentModel);
        comment.setId(commentIdWorker.nextId());
        ShowModel showModel = showService.selectById(commentModel.getShowId());
        cacheService.hashIncr(USER_NEW_COMMENT + showModel.getCreateUid(), String.valueOf(showModel.getId()));
        comment.setCreateTime(System.currentTimeMillis());
        return tbCommentMapper.insertSelective(comment) > 0;
    }

    @Override
    @Transactional
    public boolean deleteByShowId(Long showId) {
        List<CommentModel> commentModels = queryByShowId(showId);
        List<Long> imageIds = commentModels.stream().map(s -> s.getImages()).flatMap(images -> images.stream()).filter(id -> id != null).collect(Collectors.toList());
        imageIds.forEach(id -> imageService.delete(id));
        TbComment tbComment = new TbComment();
        tbComment.setShowId(showId);
        return tbCommentMapper.delete(tbComment) > 0;
    }
}
